
package com.tools.cleanmaster.cpucool.widget;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.SweepGradient;
import android.graphics.Typeface;
import android.graphics.drawable.BitmapDrawable;
import android.os.SystemClock;
import android.util.AttributeSet;
import android.view.View;

import com.tools.ad.util.FontsManager;
import com.tools.cleanmaster.R;

import java.lang.ref.WeakReference;

public class CpuAnimatorView extends View {
    private Resources mResources;
    private Bitmap mCpucoolerLine;
    private Bitmap mCpucoolerOutterline1;
    private Bitmap mCpucoolerOutterline2;
    private Bitmap mCpuFunIcon;
    private Bitmap mCpuCoolFinishIcon;

    private int mTotalWidth, mTotalHeight, mCenterX, mCenterY;
    private int mCpucoolerLineWidth, mCpucoolerLineHeight;
    private int mCpucoolerOutterline1Width, mCpucoolerOutterline1Height;
    private int mCpucoolerOutterline2Width, mCpucoolerOutterline2Height;
    private int mCpuFunIconWidth, mCpuFunIconHeight;
    private int mCpuCoolIconFinishWidth, mCpuCoolIconFinishHeight;
    private int mCpuFinishedOffsetX, mCpuFinishedOffsetY;
    private int mRoundRectDegree;

    private Matrix mCpuFunMatrix;
    private int mCpuFundegree = 0;
    private Paint mCpuFunPaint;
    private int mCpuFunOffsetX;
    private int mCpuFunOffsetY;
    private int mClipOffset = 100;
    private boolean mScaleFinished = false;

    private static final long SCAN_ANIMATION_TIME = 2000;
    private static final long SCAN_END_ANIMATION_TIME = 200;
    private static final long SCAN_END_ANIMATION_TIME1 = 350;
    private long mStartTime;
    private long mScanEndTime;
    private boolean mIsStartScan = true;
    private boolean mIsScanning = true;
    private boolean mIsScanFinished = false;
    private int mCurrentRotate = 0;
    private String mScanningString;

    private static final Typeface FONT_THIN = FontsManager.getFontType(FontsManager.FONT_THIN);
    private static final Typeface FONT_LIGHT = FontsManager.getFontType(FontsManager.FONT_LIGHT);

    private Paint mBackPurplePaint = new Paint();
    private Paint mBackRedPaint = new Paint();
    private Paint mBackBluePaint = new Paint();
    private Paint aroundPaint = new Paint();
    private Paint scanPaint = new Paint();
    private Paint cpuPaint = new Paint();
    private Paint textPaint = new Paint();
    private Paint mFinishPaint;
    private int mFinishAlpha = 255;
    private float mFinishScale = 1f;
    private Paint textTemPaint = new Paint();
    private Paint textTemPaint1 = new Paint();
    private Paint textOverheatedPaint = new Paint();
    private int mTextSize;
    private int mTemperatureMargin;
    private int mShineLineWidth;
    private int mTextColor;
    private int mScanBackgroundColor;
    private int mTextOverheatedColor;
    private RectF r1 = new RectF();
    private Matrix mMatrix = new Matrix();
    private int[] colors = new int[]{0x223340f3, 0xff3340f3};
    private int[] colors1 = new int[]{Color.TRANSPARENT, Color.WHITE};
    private Shader mShader;
    private Shader mShader1;
    private PorterDuffXfermode mSRCIN = new PorterDuffXfermode(PorterDuff.Mode.SRC_IN);
    private PorterDuffXfermode mDSTIN = new PorterDuffXfermode(PorterDuff.Mode.DST_IN);
    private int mTextBaseX, mTextBaseY;
    private int saveLayerCount, saveLayerCount1;
    private int textWidth;
    private WeakReference<CpuAnimatorListener> mListener;

    //通知界面可以进行结果页了
    public interface CpuAnimatorListener {
        void onCpuScanFinished();

        void onCpuCoolFinished();
    }

    public enum Status {
        IDLE, SCANNING, SCAN_END, ROTATE, COOLING, FINISHED_ANIM, FINISHED, PROTECT_TIME
    }

    private Status mStatus = Status.IDLE;
    private boolean mOverheated;
    private boolean mCoolDownFinished = false;

    public CpuAnimatorView(Context context) {
        super(context);
    }

    public CpuAnimatorView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initViews();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        switch (mStatus) {
            case SCANNING:
                drawCpuAnimation(canvas);
                break;
            case SCAN_END:
                drawCpuAnimation(canvas);
                break;
            case ROTATE:
                drawRotateState(canvas);
                break;
            case COOLING:
                drawCpuCooling(canvas);
                break;
            case FINISHED_ANIM:
                drawCpuCoolFinishAnim(canvas);
                break;
            case FINISHED:
                drawCpuCoolFinished(canvas);
                return;
            case PROTECT_TIME:
                drawCpuProtectTime(canvas);
            default:
                drawIdle(canvas);
                break;
        }
    }

    private void drawIdle(Canvas canvas) {
        drawCpuCoolAround(canvas);
        canvas.drawBitmap(mCpucoolerLine, mCenterX - mCpucoolerLineWidth / 2, mCenterY - mCpucoolerLineHeight / 2, aroundPaint);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        mTotalWidth = w;
        mTotalHeight = h;
        mCenterX = w >> 1;
        mCenterY = h >> 1;
        mShader = new SweepGradient(mCenterX, mCenterY, colors, new float[]{0.6f, 1f});
        mShader1 = new SweepGradient(mCenterX, mCenterY, colors1, new float[]{0.6f, 1f});

        //RectF对象
        r1.left = mCenterX - mCpucoolerLineWidth / 2;                                 //左边
        r1.top = mCenterY - mCpucoolerLineHeight / 2;                                 //上边
        r1.right = mCenterX + mCpucoolerLineWidth / 2;                                   //右边
        r1.bottom = mCenterY + mCpucoolerLineHeight / 2;                              //下边
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
    }

    private void initViews() {
        mResources = getResources();

        mCpucoolerOutterline1 = ((BitmapDrawable) mResources.getDrawable(R.drawable.cpucooler_outterline_ring1)).getBitmap();
        mCpucoolerOutterline1Width = mCpucoolerOutterline1.getWidth();
        mCpucoolerOutterline1Height = mCpucoolerOutterline1.getHeight();
        mCpucoolerOutterline2 = ((BitmapDrawable) mResources.getDrawable(R.drawable.cpucooler_outterline_ring2)).getBitmap();
        mCpucoolerOutterline2Width = mCpucoolerOutterline2.getWidth();
        mCpucoolerOutterline2Height = mCpucoolerOutterline2.getHeight();
        mCpucoolerLine = ((BitmapDrawable) mResources.getDrawable(R.drawable.cpucooler_lines)).getBitmap();
        mCpucoolerLineWidth = mCpucoolerLine.getWidth();
        mCpucoolerLineHeight = mCpucoolerLine.getHeight();
        mCpuFunIcon = ((BitmapDrawable) mResources.getDrawable(R.drawable.cpucooler_fan)).getBitmap();
        mCpuFunIconWidth = mCpuFunIcon.getWidth();
        mCpuFunIconHeight = mCpuFunIcon.getHeight();
        mCpuFunOffsetX = mCpuFunIconWidth / 2;
        mCpuFunOffsetY = mCpuFunIconHeight / 2;
        mCpuCoolFinishIcon = ((BitmapDrawable) mResources.getDrawable(R.drawable.cpu_cooler_finish)).getBitmap();
        mCpuCoolIconFinishWidth = mCpuCoolFinishIcon.getWidth();
        mCpuCoolIconFinishHeight = mCpuCoolFinishIcon.getHeight();
        mCpuFinishedOffsetX = mCpuCoolIconFinishWidth / 2;
        mCpuFinishedOffsetY = mCpuCoolIconFinishHeight / 2;

        mCpuFunPaint = new Paint();
        mCpuFunPaint.setAntiAlias(true);
        mCpuFunPaint.setFilterBitmap(true);
        mCpuFunMatrix = new Matrix();
        loadResources();

        mBackPurplePaint.setColor(mResources.getColor(R.color.cpu_cool_purple_background));
        mBackRedPaint.setColor(mResources.getColor(R.color.cpu_cool_red_background));
        mBackBluePaint.setColor(mResources.getColor(R.color.cpu_cool_blue_background));
        textPaint.setTextSize(mTextSize);
        textPaint.setColor(mTextColor);
        textPaint.setAntiAlias(true);
        mFinishPaint = new Paint();
        textPaint.setTypeface(FONT_LIGHT);
        textTemPaint.setTextSize(mResources.getDimensionPixelSize(R.dimen.cpu_scan_end_temperature_text_size));
        textTemPaint.setColor(mTextColor);
        textTemPaint.setAntiAlias(true);
        textTemPaint.setTypeface(FONT_THIN);
        textTemPaint1.setTextSize(mTextSize);
        textTemPaint1.setColor(mTextColor);
        textTemPaint1.setAntiAlias(true);
        textTemPaint1.setTypeface(FONT_LIGHT);
        textOverheatedPaint.setTextSize(mTextSize);
        textOverheatedPaint.setColor(mTextOverheatedColor);
        textOverheatedPaint.setAntiAlias(true);
        textOverheatedPaint.setTypeface(FONT_LIGHT);
    }

    private void loadResources() {
        mTextSize = mResources.getDimensionPixelSize(R.dimen.cpu_scan_text_size);
        mTemperatureMargin = mResources.getDimensionPixelSize(R.dimen.cpu_temperature_margin_size);
        mRoundRectDegree = mResources.getDimensionPixelSize(R.dimen.round_rect_degree);
        mShineLineWidth = mResources.getDimensionPixelSize(R.dimen.shine_line_width);
        mClipOffset = mShineLineWidth;
        mScanBackgroundColor = mResources.getColor(R.color.cpu_cool_purple_background);
        mTextColor = mResources.getColor(R.color.cpu_scan_text_color);
        mTextOverheatedColor = mResources.getColor(R.color.cpu_scan_text_color);
        mScanningString = getResources().getString(R.string.cpu_scanning_msg);
    }

    // 设置是否完成CPU降温功能
    public void setCoolDownFinished(boolean coolFinished) {
        mCoolDownFinished = coolFinished;
    }

    public void switchStatus(Status status) {
        mStatus = status;
        postInvalidate();
    }

    public void setOverHeated(boolean overHeated) {
        mOverheated = overHeated;
    }


    public void setCpuAnimationListener(CpuAnimatorListener listener) {
        mListener = new WeakReference<CpuAnimatorListener>(listener);
    }

    public void drawRotateState(Canvas canvas) {
        drawCpuCoolAround(canvas);

        if (mOverheated) {
            drawBackground(canvas, mBackRedPaint);
        } else {
            drawBackground(canvas, mBackPurplePaint);
        }
        canvas.drawBitmap(mCpucoolerLine, mCenterX - mCpucoolerLineWidth / 2, mCenterY - mCpucoolerLineHeight / 2, aroundPaint);
        canvas.drawBitmap(mCpuFunIcon, mCenterX - (mCpuFunIconWidth / 2), mCenterY - mCpuFunIconHeight / 2, mCpuFunPaint);
    }

    private void drawCpuAnimation(Canvas canvas) {
        if (mIsStartScan) {
            mIsStartScan = false;
            mStartTime = SystemClock.elapsedRealtime();
        }

        long intervalTime = SystemClock.elapsedRealtime() - mStartTime;
        if (intervalTime < SCAN_ANIMATION_TIME || (mStatus == Status.SCANNING)) {
            drawCpuScanning(canvas);
            drawCpuText(canvas, 1);
        } else if (mStatus == Status.SCAN_END) {
            if (mIsScanning) {
                mIsScanning = false;
                mScanEndTime = SystemClock.elapsedRealtime();
            }
            long intervalScanTime = SystemClock.elapsedRealtime() - mScanEndTime;
            int textMod = (int) (intervalScanTime % SCAN_END_ANIMATION_TIME);
            float textScale = 1 - (float) textMod / SCAN_END_ANIMATION_TIME;
            int cpuMod = (int) (intervalScanTime % SCAN_END_ANIMATION_TIME1);
            float cpuScale = 1 - (float) cpuMod / SCAN_END_ANIMATION_TIME1;
            if (intervalScanTime < SCAN_END_ANIMATION_TIME) {
                drawCpuScanningDown(canvas, cpuScale);
                drawCpuText(canvas, textScale);
            } else if (intervalScanTime < SCAN_END_ANIMATION_TIME1) {
                drawCpuScanningDown(canvas, cpuScale);
            } else {
                drawCpuScanningDown(canvas, 0);
                if (!mIsScanFinished) {
                    mListener.get().onCpuScanFinished();
                    mIsScanFinished = true;
                }
                return;
            }
        }
        postInvalidate();
    }

    // Cpu温度扫描时动画
    private void drawCpuScanning(Canvas canvas) {
        drawCpuScanAround(canvas);

        drawBackground(canvas, mBackPurplePaint);

        //画Cpu线
        canvas.drawBitmap(mCpucoolerLine, mCenterX - mCpucoolerLineWidth / 2, mCenterY - mCpucoolerLineHeight / 2, mBackPurplePaint);

        canvas.clipRect(r1);

        mMatrix.setRotate(mCurrentRotate, mCenterX, mCenterY);
        mCurrentRotate += 5;

        saveLayerCount = canvas.saveLayer(0, 0, mTotalWidth, mTotalHeight, null, Canvas.ALL_SAVE_FLAG);
        mShader.setLocalMatrix(mMatrix);
        scanPaint.setShader(mShader);
        canvas.drawRoundRect(r1, mRoundRectDegree, mRoundRectDegree, scanPaint);
        scanPaint.setXfermode(mSRCIN);
        canvas.drawCircle(mCenterX, mCenterY, mCenterX, scanPaint);
        scanPaint.setXfermode(null);
        canvas.restoreToCount(saveLayerCount);

        saveLayerCount1 = canvas.saveLayer(0, 0, mTotalWidth, mTotalHeight, null, Canvas.ALL_SAVE_FLAG);
        mShader1.setLocalMatrix(mMatrix);
        cpuPaint.setShader(mShader1);
        canvas.drawCircle(mCenterX, mCenterY, mCenterX, cpuPaint);
        cpuPaint.setXfermode(mDSTIN);
        canvas.drawBitmap(mCpucoolerLine, mCenterX - mCpucoolerLineWidth / 2, mCenterY - mCpucoolerLineHeight / 2, cpuPaint);
        cpuPaint.setXfermode(null);
        canvas.restoreToCount(saveLayerCount1);

    }

    // Cpu温度扫描时动画
    private void drawCpuScanningDown(Canvas canvas, float scale) {
        drawCpuScanAround(canvas);

        if (mOverheated) {
            drawBackgroundChange(canvas, mBackPurplePaint, mBackRedPaint, scale);
        } else {
            drawBackground(canvas, mBackPurplePaint);
        }

        canvas.drawBitmap(mCpucoolerLine, mCenterX - mCpucoolerLineWidth / 2, mCenterY - mCpucoolerLineHeight / 2, cpuPaint);

    }

    private void drawBackground(Canvas canvas, Paint paint) {
        canvas.drawRoundRect(r1, mRoundRectDegree, mRoundRectDegree, paint);        //绘制圆角矩形
    }

    private void drawBackgroundChange(Canvas canvas, Paint fromPaint, Paint toPaint, float scale) {
        fromPaint.setAlpha((int) (scale * 255));
        canvas.drawRoundRect(r1, mRoundRectDegree, mRoundRectDegree, fromPaint);        //绘制圆角矩形

        toPaint.setAlpha((int) ((1 - scale) * 255));
        canvas.drawRoundRect(r1, mRoundRectDegree, mRoundRectDegree, toPaint);        //绘制圆角矩形

    }

    private void drawCpuText(Canvas canvas, float scale) {
        textWidth = (int) textPaint.measureText(mScanningString);
        textPaint.setAlpha((int) (scale * 255));
        mTextBaseX = mCenterX - (textWidth >> 1);
        mTextBaseY = mCenterY;
        canvas.drawText(mScanningString, mTextBaseX, mTextBaseY, textPaint);
    }

    private int coolTime = 0;

    private void drawCpuCooling(Canvas canvas) {
        canvas.save();
        int top = mCenterY - mCpucoolerOutterline2Width / 2 + mClipOffset;
        int left = mCenterX - mCpucoolerOutterline2Width / 2 + mClipOffset;
        int right = mCenterX + mCpucoolerOutterline2Width / 2 - mClipOffset;
        int bottom = mCenterY + mCpucoolerOutterline2Height / 2 - mClipOffset;

        canvas.clipRect(
                top,
                left,
                right,
                bottom
        );

        drawCpuCoolAround(canvas);
        mClipOffset = mClipOffset - 1;
        if (mClipOffset <= 0) {
            coolTime += 1;
            mClipOffset = mShineLineWidth;
        }
        if (coolTime == 0) {
            if (mOverheated) {
                drawBackground(canvas, mBackRedPaint);
            } else {
                drawBackground(canvas, mBackPurplePaint);
            }
        } else if (coolTime == 1) {
            int cpuMod = ((mShineLineWidth - mClipOffset) % mShineLineWidth);
            float scale = 1 - (float) cpuMod / mShineLineWidth;
            if (mOverheated) {
                drawBackgroundChange(canvas, mBackRedPaint, mBackBluePaint, scale);
            } else {
                drawBackgroundChange(canvas, mBackPurplePaint, mBackBluePaint, scale);
            }
        } else {
            drawBackground(canvas, mBackBluePaint);
            if (mCoolDownFinished) {
                switchStatus(Status.FINISHED_ANIM);
                mClipOffset = mShineLineWidth;
            }
        }
        canvas.drawBitmap(mCpucoolerLine, mCenterX - mCpucoolerLineWidth / 2, mCenterY - mCpucoolerLineHeight / 2, aroundPaint);
        drawCpuCoolingFanner(canvas);
        canvas.restore();
        postInvalidate();
    }

    private void drawCpuProtectTime(Canvas canvas) {
        canvas.save();
        int top = mCenterY - mCpucoolerOutterline2Width / 2 + mClipOffset;
        int left = mCenterX - mCpucoolerOutterline2Width / 2 + mClipOffset;
        int right = mCenterX + mCpucoolerOutterline2Width / 2 - mClipOffset;
        int bottom = mCenterY + mCpucoolerOutterline2Height / 2 - mClipOffset;

        canvas.clipRect(
                top,
                left,
                right,
                bottom
        );

        drawCpuCoolAround(canvas);
        mClipOffset = mClipOffset - 1;
        if (mClipOffset <= 0) {
            mClipOffset = mShineLineWidth;
            switchStatus(Status.FINISHED_ANIM);
            return;
        }
        drawBackground(canvas, mBackBluePaint);
        canvas.drawBitmap(mCpucoolerLine, mCenterX - mCpucoolerLineWidth / 2, mCenterY - mCpucoolerLineHeight / 2, aroundPaint);
        drawCpuCoolingFanner(canvas);
        canvas.restore();
        postInvalidate();
    }

    // 画cpu降温完成界面
    private void drawCpuCoolFinished(Canvas canvas) {
        drawCpuScanAround(canvas);
        drawBackground(canvas, mBackBluePaint);
        canvas.drawBitmap(mCpucoolerLine, mCenterX - mCpucoolerLineWidth / 2, mCenterY - mCpucoolerLineHeight / 2, aroundPaint);
        drawCpuCoolOkIcon(canvas);
    }

    private boolean mCoolFinished = false;
    private static int ANIM_INCREMENT = 17;
    private static int ALPHA_ANIM_INCREMENT = 255 / ANIM_INCREMENT;
    private static float SCALE_ANIM_INCREMENT = 1f / ANIM_INCREMENT;

    // 画cpu降温完成的动画
    private void drawCpuCoolFinishAnim(Canvas canvas) {
        canvas.save();

        int top = mCenterY - mCpucoolerOutterline2Width / 2 + mClipOffset;
        int left = mCenterX - mCpucoolerOutterline2Width / 2 + mClipOffset;
        int right = mCenterX + mCpucoolerOutterline2Width / 2 - mClipOffset;
        int bottom = mCenterY + mCpucoolerOutterline2Height / 2 - mClipOffset;

        canvas.clipRect(
                top,
                left,
                right,
                bottom
        );

        mClipOffset = mClipOffset - 1;
        if (mClipOffset <= 0) {
            mClipOffset = mShineLineWidth;
        }
        drawCpuScanAround(canvas);
        drawBackground(canvas, mBackBluePaint);
        canvas.drawBitmap(mCpucoolerLine, mCenterX - mCpucoolerLineWidth / 2, mCenterY - mCpucoolerLineHeight / 2, aroundPaint);
        if (mScaleFinished) {
            mFinishAlpha = mFinishAlpha + ALPHA_ANIM_INCREMENT;
            mFinishScale = mFinishScale + SCALE_ANIM_INCREMENT;
            drawCpuCoolOkStart(canvas);
            if (mListener.get() != null && !mCoolFinished) {
                mListener.get().onCpuCoolFinished();
                mCoolFinished = true;
            }
        } else {
            mFinishAlpha = mFinishAlpha - ALPHA_ANIM_INCREMENT;
            mFinishScale = mFinishScale - SCALE_ANIM_INCREMENT;
            drawCpuCoolFunFinish(canvas);
        }
        if (mFinishAlpha <= 0) {
            mScaleFinished = true;
            mFinishScale = 0f;
        }
        if (mFinishAlpha >= 255) {
            mStatus = Status.FINISHED;
        }
        canvas.restore();
        postInvalidate();
    }

    /*
    画 cpu 降温时的小风扇
     */
    private void drawCpuCoolingFanner(Canvas canvas) {
        mCpuFunMatrix.reset();
        mCpuFunMatrix.postRotate(mCpuFundegree, mCpuFunOffsetX, mCpuFunOffsetY);
        mCpuFunMatrix.postTranslate(mCenterX - mCpuFunOffsetX, mCenterY - mCpuFunOffsetY);
        mCpuFundegree = mCpuFundegree + 15;
        canvas.drawBitmap(mCpuFunIcon, mCpuFunMatrix, mCpuFunPaint);
    }

    // 画Cpu扫描时周围的线
    private void drawCpuScanAround(Canvas canvas) {
        canvas.drawBitmap(mCpucoolerOutterline1, mCenterX - (mCpucoolerOutterline1Width / 2), mCenterY - mCpucoolerOutterline1Height / 2, aroundPaint);

    }

    // 画Cpu降温时周围的线和cpu背后的cpu线
    private void drawCpuCoolAround(Canvas canvas) {
        canvas.drawBitmap(mCpucoolerOutterline2, mCenterX - (mCpucoolerOutterline2Width / 2), mCenterY - mCpucoolerOutterline2Height / 2, mCpuFunPaint);
    }

    /*
    画cpu小风扇消失
     */
    private void drawCpuCoolFunFinish(Canvas canvas) {
        mCpuFunMatrix.reset();
        mFinishPaint.setAlpha(mFinishAlpha);
        mCpuFunMatrix.postTranslate(mCenterX - mCpuFunOffsetX, mCenterY - mCpuFunOffsetY);
        mCpuFunMatrix.postScale(mFinishScale, mFinishScale, mCenterX, mCenterY);
        canvas.drawBitmap(mCpuFunIcon, mCpuFunMatrix, mFinishPaint);
    }

    /*
    画对号出来动画
     */
    private void drawCpuCoolOkStart(Canvas canvas) {
        mCpuFunMatrix.reset();
        mFinishPaint.setAlpha(mFinishAlpha);
        mCpuFunMatrix.postTranslate(mCenterX - mCpuFinishedOffsetX, mCenterY - mCpuFinishedOffsetY);
        mCpuFunMatrix.postScale(mFinishScale, mFinishScale, mCenterX, mCenterY);
        canvas.drawBitmap(mCpuCoolFinishIcon, mCpuFunMatrix, mFinishPaint);
    }

    /*
    画对号出来
    */
    private void drawCpuCoolOkIcon(Canvas canvas) {
        mCpuFunMatrix.reset();
        mCpuFunMatrix.setTranslate(mCenterX - mCpuFinishedOffsetX, mCenterY - mCpuFinishedOffsetY);
        canvas.drawBitmap(mCpuCoolFinishIcon, mCpuFunMatrix, mCpuFunPaint);
    }
}
